<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />

		<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
		Remove this if you use the .htaccess -->
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

		<title>Simplex</title>
		<meta name="description" content="" />
		<meta name="author" content="hema0004" />

		<meta name="viewport" content="width=device-width; initial-scale=1.0" />
		<style>
			.axis path, .axis line {
				fill: none;
				stroke: black;
				shape-rendering: crispEdges;
			}

			.axis text {
				font-family: sans-serif;
				font-size: 11px;
			}
		</style>
		<script type="text/javascript" src="numeric-1.2.6.js"></script>
		<script src="d3.v3.min.js"></script>
		<script type="text/javascript">
			var zeilenNebenbedingungen;
			var zielfunktion;
			var nebenbedingungen;
			var vorzeichen;
			var nbalt = [];
			var nbneu = [];
			var rechteSeite;
			var idxBiLe;
			var zeilenGesamt;
			var spaltenGesamt;
			var phase;
			var tab;
			var minIdxVector;
			var aktion = 0;
			var minIdxSpalte;
			var minIdxZeile;
			var minSpalte;
			var minZeile;
			var zeilenNamen = new Array();
			var spaltenNamen = new Array();
			var idxPivotspalteNegativ = new Array();
			var str1 = 0;
			var allBaseLines = new Array();
			function initial() {
				document.getElementById("eingabe").onclick = generate_table;
			}

			function generate_table() {
				// get the reference for the body
				var body = document.getElementsByTagName("body")[0];
				str1 = document.getElementById("zf_txt").value;
				str1 = parseInt(str1);
				zeilenNebenbedingungen = document.getElementById("nb_txt").value;
				zeilenNebenbedingungen = parseInt(zeilenNebenbedingungen);
				// creates a <table> element and a <tbody> element
				var tbl = document.createElement("table");
				var tblBody = document.createElement("tbody");

				// creating all cells
				// creates a table row
				var row = document.createElement("tr");
				var ii = 0;
				for (var j = 0; j < 2 * str1; j++) {
					// Create a <td> element and a text node, make the text
					// node the contents of the <td>, and put the <td> at
					// the end of the table row
					var cell = row.insertCell(j);
					if (j % 2 == 0) {
						var cellContent = document.createElement("input");
						cellContent.type = "text";
						cellContent.id = "zf" + ii; ++ii;
						cell.appendChild(cellContent);
					} else {
						cell.innerHTML = "x" + (j + 1) / 2;
					}

					row.appendChild(cell);
				}

				// add the row to the end of the table body
				tblBody.appendChild(row);

				// put the <tbody> in the <table>
				tbl.appendChild(tblBody);
				// appends <table> into <body>
				body.appendChild(tbl);
				// sets the border attribute of tbl to 2;
				tbl.setAttribute("border", "2");

				tbl = document.createElement("table");
				tblBody = document.createElement("tbody");
				var ii = 0;
				var ij = 0;
				var ji = 0;
				for (var i = 0; i < zeilenNebenbedingungen; ++i) {
					var row = document.createElement("tr");
					for ( j = 0; j < 2 * str1 + 2; j++) {
						// Create a <td> element and a text node, make the text
						// node the contents of the <td>, and put the <td> at
						// the end of the table row
						var cell = row.insertCell(j);
						if ((j % 2 == 0) && (j < 2 * str1)) {
							var cellContent = document.createElement("input");
							cellContent.type = "text";
							cellContent.id = "nb" + ii; ++ii;
							cell.appendChild(cellContent);
						} else if ((j % 2 != 0) && (j < 2 * str1)) {
							cell.innerHTML = "x" + (j + 1) / 2;
						} else if (j == 2 * str1) {
							var cellContent = document.createElement("select");
							cellContent.id = "vz" + ji; ++ji;
							cellContent.style.width = "50px";
							var option = document.createElement("option");
							option.setAttribute("value", 1);
							option.innerHTML = "<=";
							cellContent.appendChild(option);

							option = document.createElement("option");
							option.setAttribute("value", 2);
							option.innerHTML = ">=";
							cellContent.appendChild(option);
							cell.appendChild(cellContent);
						} else {
							var cellContent = document.createElement("input");
							cellContent.type = "text";
							cellContent.id = "rs" + ij; ++ij;
							cell.appendChild(cellContent);
						}

						row.appendChild(cell);
					}
					// add the row to the end of the table body
					tblBody.appendChild(row);
				}

				// put the <tbody> in the <table>
				tbl.appendChild(tblBody);
				// appends <table> into <body>
				body.appendChild(tbl);
				// sets the border attribute of tbl to 2;
				tbl.setAttribute("border", "2");
				var button1 = document.createElement("button");
				button1.onclick = abschicken;
				button1.style.width = "100px";
				button1.style.height = "50px";
				button1.id = "b1_id"
				body.appendChild(button1);
			}

			function getMinSpalte() {
				var F = new Array(spaltenGesamt - 1);
				if (phase == 2) {
					for (var j = 0; j < spaltenGesamt - 1; ++j) {
						F[j] = tab[zeilenNebenbedingungen][j];
					}
					phaseShift = 1;
				} else {
					for (var j = 0; j < spaltenGesamt - 1; ++j) {
						F[j] = tab[zeilenNebenbedingungen+1][j];
					}
					phaseShift = 2;
				}
				minSpalte = getMinimum(F);
				if (minIdxVector.length > 1) {
					markMultiMinSpalte();
					return 3;
				} else {
					minIdxSpalte = minIdxVector[0];
					markMinSpalte();
					if (Math.abs(minSpalte) < 1e-9) {
						return 10;
					} else {
						return 3;
					}
				}
			}

			function markMultiMinSpalte() {
				var tbl = document.getElementsByTagName("table")[0];
				var row = tbl.rows[zeilenGesamt];
				for (var i = 0; i < minIdxVector.length; ++i) {
					var cell = row.cells[minIdxVector[i] + 1];
					cell.setAttribute('style', 'background-color: #6495ED');
					cell.onclick = auswahl;
				}
			}

			function auswahl() {
				minIdxSpalte = this.cellIndex - 1;
				var tbl = document.getElementsByTagName("table")[0];
				var row = tbl.rows[zeilenGesamt];
				for (var i = 0; i < minIdxVector.length; ++i) {
					var cell = row.cells[minIdxVector[i] + 1];
					if (minIdxVector[i] == minIdxSpalte) {
						cell.setAttribute('style', 'background-color: #4169E1');
					} else {
						cell.setAttribute('style', 'background-color: #FFFFFF');
					}
				}
			}

			function markMinSpalte() {
				var tbl = document.getElementsByTagName("table")[0];
				var row = tbl.rows[zeilenGesamt];
				var cell = row.cells[minIdxSpalte + 1];
				cell.setAttribute('style', 'background-color: #4169E1');
			}

			function getPivotSpalteLoes() {
				var pivotspalte = new Array(zeilenNebenbedingungen);
				var bspalte = new Array(zeilenNebenbedingungen);
				var idxPivotspaltePositiv = new Array(zeilenNebenbedingungen);
				var pivotspalteLoesung = new Array(zeilenNebenbedingungen);
				idxPivotspalteNegativ = new Array();
				for (var i = 0; i < zeilenNebenbedingungen; ++i) {
					pivotspalte[i] = tab[i][minIdxSpalte];
					bspalte[i] = tab[i][spaltenGesamt - 1];
					pivotspalteLoesung[i] = bspalte[i] / pivotspalte[i];
					if (pivotspalte[i] > 0) {
						idxPivotspaltePositiv[i] = 1;
					}
					if (pivotspalte[i] <= 0) {
						idxPivotspalteNegativ.push(i);
					}
				}
				plotTable(true);
				var tbl = document.getElementsByTagName("table")[0];
				var row1 = tbl.rows[zeilenGesamt];
				var cell1 = row1.cells[minIdxSpalte + 1];
				cell1.setAttribute('style', 'background-color: #4169E1');
				var tabRow0 = document.getElementsByTagName("table")[0].
				rows[0].cells;
				tabRow0[spaltenGesamt + 1].innerHTML = "ai/b";
				for (var i = 0; i < pivotspalteLoesung.length; ++i) {
					var tabRow = document.getElementsByTagName("table")[0].
					rows[i + 1].cells;
					tabRow[spaltenGesamt + 1].innerHTML = precise_round(pivotspalteLoesung[i], 4);
				}
				var nnz = true;
				for (var i = 0; i < idxPivotspaltePositiv.length; ++i) {
					if (idxPivotspaltePositiv[i] != 0) {
						nnz = false;
						break;
					}
				}
				if ((phase == 2) && (nnz)) {
					return 20;
				}
				for (var i = 0; i < idxPivotspalteNegativ.length; ++i) {
					pivotspalteLoesung[idxPivotspalteNegativ[i]] = Number.POSITIVE_INFINITY;
				}
				minZeile = getMinimum(pivotspalteLoesung);
				var nichtnegativ = new Array(zeilenNebenbedingungen);
				for (var i = 0; i < zeilenNebenbedingungen; ++i) {
					nichtnegativ[i] = tab[i][spaltenGesamt - 1] - minZeile * tab[i][minIdxSpalte];
					if (Math.abs(nichtnegativ[i]) < 1e-9) {
						nichtnegativ[i] = 0;
					}
				}
				var idxNichtNegativ = new Array();
				for (var i = 0; i < nichtnegativ.length; ++i) {
					if (nichtnegativ[i] < 0) {
						idxNichtNegativ.push(i);
					}
				}
				if (idxNichtNegativ.length > 0) {
					return 30;
				}
				minIdxZeile = minIdxVector[0];
				if (idxPivotspalteNegativ.length == 0) {
					return 6;
				} else {
					return 5;
				}
			}

			function deletePivotSpalteNegativ() {
				var tbl = document.getElementsByTagName("table")[0];
				for (var i = 0; i < idxPivotspalteNegativ.length; ++i) {
					var row = tbl.rows[idxPivotspalteNegativ[i] + 1];
					var cell = row.cells[spaltenGesamt + 1];
					cell.innerHTML = "";
				}
				return 6;
			}

			function markMultiMinZeile() {
				var tbl = document.getElementsByTagName("table")[0];
				for (var i = 0; i < minIdxVector.length; ++i) {
					var row = tbl.rows[minIdxVector[i] + 1];
					var cell = row.cells[spaltenGesamt + 1];
					cell.setAttribute('style', 'background-color: #6495ED');
					cell.onclick = auswahl2;
				}
			}

			function getMinZeile() {
				if (minIdxVector.length > 1) {
					markMultiMinZeile();
				} else {
					var tbl = document.getElementsByTagName("table")[0];
					var row2 = tbl.rows[minIdxZeile + 1];
					var cell2 = row2.cells[spaltenGesamt + 1];
					cell2.setAttribute('style', 'background-color: #4169E1');
				}

				return 7;
			}

			function auswahl2() {
				minIdxZeile = this.parentElement.rowIndex - 1;
				var tbl = document.getElementsByTagName("table")[0];
				for (var i = 0; i < minIdxVector.length; ++i) {
					console.log(minIdxVector[i])
					var row = tbl.rows[minIdxVector[i] + 1];
					var cell = row.cells[spaltenGesamt + 1];
					if (minIdxVector[i] == minIdxZeile) {
						cell.setAttribute('style', 'background-color: #4169E1');
					} else {
						cell.setAttribute('style', 'background-color: #FFFFFF');
					}
				}
			}

			function getPivotElement() {
				var tbl = document.getElementsByTagName("table")[0];
				var row2 = tbl.rows[minIdxZeile + 1];
				var cell2 = row2.cells[minIdxSpalte + 1];
				cell2.setAttribute('style', 'background-color: #FF0000');
				return 8;
			}

			function getNewTable() {
				var pivotzeile = new Array(spaltenGesamt - 1);
				var pivotzeile2 = new Array(spaltenGesamt);
				for (var i = 0; i < spaltenGesamt - 1; ++i) {
					pivotzeile[i] = tab[minIdxZeile][i] * -1;
					pivotzeile2[i] = tab[minIdxZeile][i];
				}
				pivotzeile2[spaltenGesamt - 1] = tab[minIdxZeile][spaltenGesamt - 1];
				var bvtausch1 = new Array();
				for (var i = 0; i < pivotzeile.length; ++i) {
					bvtausch1.push(pivotzeile[i]);
				}
				bvtausch1.push(tab[minIdxZeile][spaltenGesamt - 1]);
				bvtausch1[minIdxSpalte] = 0;
				var pivotElement = tab[minIdxZeile][minIdxSpalte];
				var bvtausch2 = new Array(bvtausch1.length);
				for (var i = 0; i < bvtausch1.length; ++i) {
					bvtausch2[i] = bvtausch1[i] / pivotElement;
				}
				for (var i = 0; i < zeilenNebenbedingungen + phaseShift; ++i) {
					var bvtausch3 = new Array(bvtausch2.length);
					for (var j = 0; j < bvtausch2.length; ++j) {
						bvtausch3[j] = tab[i][minIdxSpalte] * bvtausch2[j];
					}
					bvtausch3[bvtausch3.length - 1] *= -1;
					tab[i][minIdxSpalte] = 0;
					for (var j = 0; j < bvtausch3.length; ++j) {
						tab[i][j] += bvtausch3[j];
					}
				}
				for (var i = 0; i < spaltenGesamt; ++i) {
					tab[minIdxZeile][i] = pivotzeile2[i] / pivotElement;
				}
				zeilenNamen[minIdxZeile] = "x" + (minIdxSpalte + 1);
				plotTable(false);
				if (phase == 1) {
					if (Math.abs(tab[tab.length-1][tab[0].length - 1]) < 1e-9) {
						phase = 2;
						return 10;
					}
				}
				return 1;
			}

			function markNull() {
				var tbl = document.getElementsByTagName("table")[0];
				var row2 = tbl.rows[tab.length];
				var cell2 = row2.cells[tab[0].length];
				cell2.setAttribute('style', 'background-color: #FF0000');
				return 40;
			}

			function precise_round(num, decimals) {
				return Math.round(num * Math.pow(10, decimals)) / Math.pow(10, decimals);
			}

			function getMinimum(v) {
				var min_Idx_Vector = new Array();
				var min_V;

				for (var i = 0; i < v.length; ++i) {
					if (i == 0) {
						min_V = v[i];
					} else {
						if (v[i] < min_V) {
							min_V = v[i];
						}
					}
				}
				for (var i = 0; i < v.length; ++i) {
					if (v[i] == min_V) {
						min_Idx_Vector.push(i);
					}
				}
				minIdxVector = min_Idx_Vector;

				return min_V;
			}

			function starten() {
				if (phase == 1) {
					//document.getElementById("txtAusgabe").innerHTML = "Test";
					return 1;
				} else {
					spaltenGesamt = zielfunktion.length + zeilenNebenbedingungen + 1;
					zeilenGesamt = zeilenNebenbedingungen + 1;
					var v1 = new Array(zeilenGesamt);
					for (var i = 0; i < v1.length; ++i) {
						v1[i] = new Array(spaltenGesamt);
						for (var j = 0; j < spaltenGesamt - 1; ++j) {
							v1[i][j] = tab[i][j];
						}
						v1[i][spaltenGesamt - 1] = tab[i][tab[0].length - 1];
					}
					tab.length = zeilenGesamt;
					spaltenNamen = [];
					for (var i = 0; i < v1.length; ++i) {
						tab[i].length = spaltenGesamt;
						for (var j = 0; j < spaltenGesamt; ++j) {
							tab[i][j] = v1[i][j];
							if ((i == 0) && (j < (spaltenGesamt - 1))) {
								spaltenNamen.push("x" + (j + 1));
							}
						}
					}
					spaltenNamen.push("b");
					plotTable(false);
					return 1;
				}
			}

			function ablauf() {
				switch(aktion) {
					case 0:
						aktion = starten();
						break;
					case 1:
						aktion = getMinSpalte();
						break;
					case 2:
						aktion = markMinSpalteMultiMin();
						break;
					case 3:
						aktion = getPivotSpalteLoes();
						break;
					case 5:
						aktion = deletePivotSpalteNegativ();
						break;
					case 6:
						aktion = getMinZeile();
						break;
					case 7:
						aktion = getPivotElement();
						break;
					case 8:
						aktion = getNewTable();
						break;
					case 10:
						aktion = markNull();
						break;
					case 40:
						aktion = starten();
						break;
				}

			}

			function getVector(str_v, li) {
				var v = [];
				for (var i = 0; i < li; ++i) {
					var vi = document.getElementById(str_v + i);
					v.push(parseInt(vi.value));
				}
				return v;
			}

			function getVZ() {
				var v = ""
				for (var i = 0; i < zeilenNebenbedingungen; ++i) {
					var vi = document.getElementById("vz" + i);
					if (vi.value == 1) {
						v += "<";
					} else {
						v += ">";
					}
				}
				return v;
			}

			function abschicken() {
				zielfunktion = getVector("zf", str1);
				nebenbedingungen = getVector("nb", str1 * zeilenNebenbedingungen);
				rechteSeite = getVector("rs", zeilenNebenbedingungen);
				rechteSeiteAlt = getVector("rs", zeilenNebenbedingungen);
				vorzeichen = getVZ();
				var groesserGleich = new Array(zeilenNebenbedingungen);
				var phaseShift = 1;
				var anzahlHilfsvariablen = 0;
				var body = document.getElementsByTagName("body")[0];
				var tbl1 = document.getElementsByTagName("table")[0];
				var tbl2 = document.getElementsByTagName("table")[1];
				body.removeChild(tbl1);
				body.removeChild(tbl2);
				body.removeChild(document.getElementById("f1"));
				body.removeChild(document.getElementById("b1_id"));
				for (var i = 0; i < zeilenNebenbedingungen; ++i) {
					str_i = vorzeichen.charAt(i);
					if (str_i == ">") {
						phaseShift = 2;
						for (var j = 0; j < zielfunktion.length; ++j) {
							nebenbedingungen[i * zielfunktion.length + j] *= -1;
						}
						rechteSeite[i] *= -1;
						groesserGleich[i] = -1; ++anzahlHilfsvariablen;
					} else {
						groesserGleich[i] = 1;
					}
				}
				idxBiLe = groesserGleich;
				zeilenGesamt = zeilenNebenbedingungen + phaseShift;
				spaltenGesamt = zielfunktion.length + zeilenNebenbedingungen + anzahlHilfsvariablen + 1;
				var v = new Array(zeilenGesamt);
				var hilfsvariablenShift = 0;
				for (var outer = 0; outer < v.length; ++outer) {
					v[outer] = new Array(spaltenGesamt);
					for (var inner = 0; inner < spaltenGesamt; ++inner) {
						v[outer][inner] = 0;
					}
				}
				var ij = 1;
				var ji = 1;
				for (var i = 0; i < zeilenNebenbedingungen; ++i) {
					if (i < zielfunktion.length) {
						zeilenNamen.push('x' + (i + 1));
					} else {
						zeilenNamen.push('y' + ji);
						ji++;
					}

					for (var j = 0; j < zielfunktion.length; ++j) {
						if (i == 0) {
							spaltenNamen.push('x' + ij); ++ij;
						}
						v[i][j] = nebenbedingungen[i * zielfunktion.length + j] * groesserGleich[i];
					}
					for (var j = 0; j < zeilenNebenbedingungen; ++j) {
						if (i == 0) {
							spaltenNamen.push('x' + ij); ++ij;
						}
						if (i == j) {
							v[i][zielfunktion.length + j] = 1 * groesserGleich[i];
						} else {
							v[i][zielfunktion.length + j] = 0;
						}
					}
					v[i][spaltenGesamt - 1] = rechteSeite[i] * groesserGleich[i];
					if (groesserGleich[i] == -1) {
						v[i][zielfunktion.length + zeilenNebenbedingungen + hilfsvariablenShift] = 1;
						hilfsvariablenShift++;
					}
				}
				zeilenNamen.push('F');
				for ( i = 0; i < zeilenNebenbedingungen; ++i) {
					var zNeu = []
					var zNeu2 = []
					for ( j = 0; j < zielfunktion.length + zeilenNebenbedingungen; ++j) {
						zNeu.push(v[i][j]);
						zNeu2.push(v[i][j]);
						if ((j < zielfunktion.length) && (groesserGleich[i] == -1)) {
							zNeu2[j] = zNeu2[j] * -1;
						}
					}
					nbalt.push(zNeu);
					nbneu.push(zNeu2);
				}
				if (phaseShift == 2) {
					zeilenNamen.push("F'");
					phase = 1;
					var summeRechteSeite = 0;
					for (var j = 0; j < spaltenGesamt - anzahlHilfsvariablen - 1; ++j) {
						var summeFStrich_i = 0;
						for (var i = 0; i < zeilenNebenbedingungen; ++i) {
							if (groesserGleich[i] == -1) {
								summeFStrich_i += v[i][j];
								if (j == 0) {
									summeRechteSeite += rechteSeite[i] * -1;
								}
							}
						}
						v[zeilenNebenbedingungen+1][j] = summeFStrich_i * -1;
					}
					v[zeilenNebenbedingungen+1][spaltenGesamt - 1] = summeRechteSeite * -1;
					for (var j = 0; j < zielfunktion.length; ++j) {
						v[zeilenNebenbedingungen][j] = zielfunktion[j] * -1;
					}
					for (var j = 0; j < anzahlHilfsvariablen; ++j) {
						spaltenNamen.push('y' + (j + 1));
					}
					for ( i = 0; i < zeilenNebenbedingungen; ++i) {
						for ( j = 0; j < spaltenGesamt; ++j) {

						}
					}
				} else {
					phase = 2;
				}
				tab = v;
				spaltenNamen.push('b');
				var div1 = document.createElement("div");
				div1.id = "div1";
				body.appendChild(div1);
				plotTable(false);
				var button2 = document.createElement("button");
				var div2 = document.createElement("div");
				div2.id = "div2";
				body.appendChild(div2);
				button2.onclick = ablauf;
				button2.style.width = "100px";
				button2.style.height = "50px";
				button2.id = "start"
				body.appendChild(button2);
				var vert = extrpts(nbalt, rechteSeiteAlt);
				var vertFinal = vert.splice(0, 2);
				var d = extrdir(nbneu);
				var pts = getPoints(vertFinal);

				var ch = getConvexHull(pts);
				//Width and height
				var xMin = vertFinal[0].min();
				var xMax = vertFinal[0].max();
				var yMin = vertFinal[1].min();
				var yMax = vertFinal[1].max();
				xSpan = xMax - xMin;
				ySpan = yMax - yMin;
				if (xSpan > ySpan) {
					var w = 400;
					var h = (ySpan * w) / xSpan;
				} else {
					var h = 400;
					var w = (xSpan * h) / ySpan;
				}
				var padding = 30;
				var div3 = document.createElement("div");
				div3.id = "div3";
				body.appendChild(div3);
				var svg = d3.select(div3).append("svg").attr("width", w)// <-- Here
				.attr("height", h);
				var xScale = d3.scale.linear().domain([d3.min(pts, function(d) {
					return d[0];
				}), d3.max(pts, function(d) {
					return d[0];
				})]).range([padding, w - padding * 2]);
				var yScale = d3.scale.linear().domain([d3.min(pts, function(d) {
					return d[1];
				}), d3.max(pts, function(d) {
					return d[1];
				})]).range([h - padding, padding]);
				poly = [];
				for (var i = 0; i < ch.length; ++i) {
					var obj = {
						x : ch[i][0][0],
						y : ch[i][0][1]
					};
					poly.push(obj);
				}

				svg.selectAll("polygon").data([poly]).enter().append("polygon").attr("points", function(d) {
					return d.map(function(d) {
						return [xScale(d.x), yScale(d.y)].join(",");
					}).join(" ");
				}).attr("stroke", "blue").attr("stroke-width", 1).attr("fill", "red");
				var xAxis = d3.svg.axis().scale(xScale).orient("bottom");
				svg.append("g").attr("class", "axis")//Assign "axis" class
				.attr("transform", "translate(0," + (h - padding) + ")").call(xAxis);
				//Define Y axis
				var yAxis = d3.svg.axis().scale(yScale).orient("left");
				//Create Y axis
				svg.append("g").attr("class", "axis").attr("transform", "translate(" + padding + ",0)").call(yAxis);
			}

			function plotTable(ls) {
				var div1 = document.getElementById("div1");
				var tbl = document.getElementsByTagName("table")[0];
				if (tbl) {
					div1.removeChild(tbl);
				}
				var tbl = document.createElement("table");
				var tblBody = document.createElement("tbody");
				var ij = 1;
				if (ls == true) {
					sp = spaltenGesamt + 2;
				} else {
					sp = spaltenGesamt + 1;
				}
				for (var i = 0; i < zeilenGesamt + 1; ++i) {
					var row = document.createElement("tr");
					for (var j = 0; j < sp; ++j) {
						if ((i == 0) || (j == 0)) {
							var cell = document.createElement("th");
						} else {
							var cell = document.createElement("td");
						}
						if ((i == 0) && (j == 0)) {
							var cellText = document.createTextNode("");
						} else if ((i == 0) && (j < spaltenGesamt + 1)) {
							var cellText = document.createTextNode(spaltenNamen[j - 1]);
						} else if ((i > 0) && (j == 0)) {
							var cellText = document.createTextNode(zeilenNamen[i - 1]);
						} else if (j == spaltenGesamt + 1) {
							var cellText = document.createTextNode("");
						} else {
							var cellText = document.createTextNode(precise_round(tab[i-1][j - 1], 4));
						}
						cell.appendChild(cellText);
						row.appendChild(cell);
					}
					tblBody.appendChild(row);
				}
				tbl.appendChild(tblBody);
				div1.appendChild(tbl);
				tbl.setAttribute("border", "2");

			}

			function getPoints(v) {
				vNeu = [];
				for (var i = 0; i < v[0].length; ++i) {
					var zNeu = [];
					zNeu.push(precise_round(v[0][i], 4));
					zNeu.push(precise_round(v[1][i], 4));
					vNeu.push(zNeu);
				}
				return vNeu;
			}

			function extrdir(A) {
				var m = A.length;
				var n = A[0].length;
				A.push(numeric.rep([n], 1))
				var b = numeric.rep([m], 0);
				b.push(1);
				var d = extrpts(A, b)
			}

			function extrpts(A, b_) {
				var m = A.length;
				var n = A[0].length;
				var vert = new Array();
				var nc = [];
				var ncArray = [];
				for (var i = 1; i < m + 1; ++i) {
					nc.push(i);
				}
				var k = nc.length;
				ncArray.push(nc);
				nv = BinomialKoeffizient(n, k);
				for ( i = 0; i < nv - 1; ++i) {
					var ncNeu = nchoosek1(nc, n + 1, k);
					ncArray.push(ncNeu);
					nc = ncNeu;
				}
				for ( i = 0; i < ncArray.length; ++i) {
					var subA = getSubMatrix(A, ncArray[i], m);
					var x = numeric.solve(subA, b_);
					if (checkDirections(x)) {
						var y = sortY(x, ncArray[i], n);
						vert.push(y);
					}
				}
				if (vert.length > 0) {
					var vertNeu = delcols(vert);
					var vertNeuTranspose = numeric.transpose(vertNeu);
					return vertNeuTranspose;
				} else {
					return vert
				}

			}

			function delcols(d) {
				var dNeu = union_arrays(d);
				var n = dNeu.length;
				var o = [];
				var dToSort = [];
				for (var i = 0; i < n; ++i) {
					dToSort.push(dNeu[i][0])
				}
				var idxNeu = sortWithIndeces(dToSort);
				var dNeuSort = new Array(dNeu.length)
				for (var i = 0; i < n; ++i) {
					dNeuSort[i] = dNeu[idxNeu.sortIndices[i]];
				}
				if ((idxNeu[0] == idxNeu[1]) && (dNeuSort[0][1] > dNeuSort[1][1])) {
					dNeuSort[0] = dNeu[idxNeu.sortIndices[1]];
					dNeuSort[1] = dNeu[idxNeu.sortIndices[0]];
				}
				for (var i = 0; i < n; ++i) {
					var c = dNeuSort[i];
					for (var j = i + 1; j < n; ++j) {
						var n1 = numeric.norminf(numeric.sub(c, dNeuSort[j]));
						if (n1 < 1e-9) {
							o.push(j);
						}
					}
				}
				if (o.length > 0) {
					var dif = 0;
					o.sort();
					for ( i = 0; i < o.length; ++i) {
						dNeuSort.splice((o[i] - dif), 1);
						dif++;
					}
				}
				return dNeuSort;
			}

			function union_arrays(d) {
				var dNeu = [];
				var added = [];
				dNeu.push(d[0]);
				for (var i = 1; i < d.length; ++i) {
					var notSame = true;
					for (var i2 = 0; i2 < i; ++i2) {
						var eq = numeric.same(d[i2], d[i]);
						//console.log(i, i2, eq)
						if (eq) {
							notSame = false;
							break;
						}
					}
					if (notSame) {
						dNeu.push(d[i]);
						//console.log(d[i])

					}
				}
				return dNeu;
			}

			function sortWithIndeces(toSort) {
				for (var i = 0; i < toSort.length; i++) {
					toSort[i] = [toSort[i], i];
				}
				toSort.sort(function(left, right) {
					return left[0] < right[0] ? -1 : 1;
				});
				toSort.sortIndices = [];
				for (var j = 0; j < toSort.length; j++) {
					toSort.sortIndices.push(toSort[j][1]);
					toSort[j] = toSort[j][0];
				}
				return toSort;
			}

			function sortY(x_, nci, n) {
				var yTmp = [];
				for (var i = 0; i < n; i++) {
					yTmp.push(0);
				}
				for (var i = 0; i < x_.length; ++i) {
					yTmp[[nci[i] - 1]] = x_[i];
				}
				return yTmp;
			}

			function getSubMatrix(v, nci, m) {
				var subA_ = []
				for (var i = 0; i < m; ++i) {
					var Ai = [];
					for (var j = 0; j < nci.length; ++j) {
						Ai.push(v[i][nci[j] - 1]);
					}
					subA_.push(Ai);
				}
				return subA_;
			}

			function checkDirections(v) {
				var cond = true;
				for (var i = 0; i < v.length; ++i) {
					if (v[i] < 0 || v[i] == Number.POSITIVE_INFINITY || v[i] == Number.NEGATIVE_INFINITY) {
						cond = false;
						break;
					}
				}
				return cond
			}

			function BinomialKoeffizient(n, k) {
				if (k + k > n) {
					k = n - k
				}
				if (k < 0) {
					return 0
				} else {
					var Ergebnis = 1
					for ( i = 0; i < k; ) {
						// Vorsicht: "Ergebnis *= (n-i)/++i" gibt es Rundungsfehler!!
						Ergebnis = (Ergebnis * (n - i)) / ++i
					}
					return Ergebnis
				}
			}

			function nchoosek1(ncTmp, n, k) {
				var finished = 0;
				var changed = 0;
				var result = [];
				for (var i1 = 0; i1 < ncTmp.length; ++i1) {
					result[i1] = ncTmp[i1];
				}
				//console.log(ncTmp)
				if (k > 0) {
					for (var i = k - 1; !finished && !changed; i--) {
						if (result[i] < (n - 1) - (k - 1) + i) {
							result[i]++;
							if (i < k - 1) {
								for (var j = i + 1; j < k; j++) {
									result[j] = result[j - 1] + 1;
								}
							}
							changed = 1;
						}
						finished = i == 0;

					}
					if (!changed) {
						for (var i = 0; i < k; i++) {
							result[i] = i;
						}
					}
				}
				return result;
			}

			function getDistant(cpt, bl) {
				var Vy = bl[1][0] - bl[0][0];
				var Vx = bl[0][1] - bl[1][1];
				return (Vx * (cpt[0] - bl[0][0]) + Vy * (cpt[1] - bl[0][1]))
			}

			function findMostDistantPointFromBaseLine(baseLine, points) {
				var maxD = 0;
				var maxPt = new Array();
				var newPoints = new Array();
				for (var idx in points) {
					var pt = points[idx];
					var d = getDistant(pt, baseLine);

					if (d > 0) {
						newPoints.push(pt);
					} else {
						continue;
					}

					if (d > maxD) {
						maxD = d;
						maxPt = pt;
					}

				}
				return {
					'maxPoint' : maxPt,
					'newPoints' : newPoints
				}
			}

			function buildConvexHull(baseLine, points) {

				allBaseLines.push(baseLine)
				var convexHullBaseLines = new Array();
				var t = findMostDistantPointFromBaseLine(baseLine, points);
				if (t.maxPoint.length) {// if there is still a point "outside" the base line
					convexHullBaseLines = convexHullBaseLines.concat(buildConvexHull([baseLine[0], t.maxPoint], t.newPoints));
					convexHullBaseLines = convexHullBaseLines.concat(buildConvexHull([t.maxPoint, baseLine[1]], t.newPoints));
					return convexHullBaseLines;
				} else {// if there is no more point "outside" the base line, the current base line is part of the convex hull
					return [baseLine];
				}
			}

			function getConvexHull(points) {
				//find first baseline
				var maxX, minX;
				var maxPt, minPt;
				for (var idx in points) {
					var pt = points[idx];
					if (pt[0] > maxX || !maxX) {
						maxPt = pt;
						maxX = pt[0];
					}
					if (pt[0] < minX || !minX) {
						minPt = pt;
						minX = pt[0];
					}
				}
				var ch = [].concat(buildConvexHull([minPt, maxPt], points), buildConvexHull([maxPt, minPt], points))
				return ch;
			}


			Array.prototype.max = function() {
				var max = this[0];
				var len = this.length;
				for (var i = 1; i < len; i++)
					if (this[i] > max)
						max = this[i];
				return max;
			}
			Array.prototype.min = function() {
				var min = this[0];
				var len = this.length;
				for (var i = 1; i < len; i++)
					if (this[i] < min)
						min = this[i];
				return min;
			}
		</script>
	</head>
	<body onload="initial()">
		<form id = "f1">
			<p>
				Anzahl Variablen Zielfunktion
				<input type="text" id="zf_txt">
			</p>
			<p>
				Anzahl Gleichungen Nebenbedingungen
				<input type="text" id="nb_txt">
			</p>
			<input type="button" id="eingabe" value="Eingabe">
		</form>
	</body>
</html>
